#include "http_curl.h"
#include "log/log.h"
#include "stdlib.h"



static size_t  writeToResponseBody(void *ptr, size_t size, size_t nmemb, void *userData)
{
    ResponseBody *responseBody = (ResponseBody *)userData;
    int total_size = size * nmemb;
    // 分配内存
    responseBody->str = realloc(responseBody->str,  total_size + 1);

    // 追加到字符串中
    memcpy(responseBody->str, ptr, total_size);
    // 添加结尾符
    responseBody->str[total_size] = '\0';
    return size;
 
}


int http_curl_get(const char *url,  size_t (*callback)(void * , size_t  , size_t  , void * )  ,void *userData)
{
    CURL *curl = NULL;
    CURLcode res_code;

    // 初始化libcurl
    curl = curl_easy_init();
    if (!curl)
    {
        printf("curl_easy_init() failed\n");
        return -1;
    }

    // 设置URL
    curl_easy_setopt(curl, CURLOPT_URL, url);
    // 设置回调函数
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);
    // 设置回调函数的参数
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, userData);
    // 执行请求
    res_code = curl_easy_perform(curl);

    //请求失败
    if (res_code != CURLE_OK)
    {
        log_error("curl_easy_perform() failed: %s\n", curl_easy_strerror(res_code));
        return -1;
    }
    //但是即使访问成功也不意味着真正的访问成功，比如返回404，500等
    //还要获取状态码
     long http_resp_code;
     curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_resp_code);
    if (http_resp_code != 200)
    {
        log_error("http_resp_code : %l \n",http_resp_code);
        return -1;
    }   
    //清理curl
    curl_easy_cleanup(curl);

    return 0;
}


/**
 * 利用 curl 实现 http 请求获得字符串
 */
int http_curl_getString(const char *url,ResponseBody *responseBody)
{

   http_curl_get(url,writeToResponseBody,responseBody);

}

/**
 * 利用 curl 实现 http 下载到对应的文件中
 */
int http_curl_downloadFile(const char *url, const char *filename)
{
    FILE *fp = fopen(filename, "wb");
    if (!fp)
    {
        log_error("fopen() failed\n");
        return -1;
    }

   if(http_curl_get(url,fwrite,fp) <0)
   {
      log_error("http_curl_get() failed\n");
      fclose(fp);
      return -1;
   }

   fclose(fp);
   return 0;
 
}